<template>
	<div>
		<el-upload :action="uploadUrl" :before-upload="handleBeforeUpload" :on-success="handleUploadSuccess"
			:on-error="handleUploadError" name="file" :show-file-list="false" :headers="headers" style="display: none"
			accept="image/*" ref="imageUpload" v-if="this.type == 'url'">
		</el-upload>

		<el-upload :action="uploadUrl" :before-upload="handleBeforeUpload" :on-success="handleUploadSuccess"
			:on-error="handleUploadError" name="file" :show-file-list="false" :headers="headers" style="display: none"
			accept="video/*" ref="videoUpload" v-if="this.type == 'url'">
		</el-upload>


		<div class="editor" ref="editor" :style="styles"></div>
	</div>
</template>

<script>
	import Quill from "quill";
	import "quill/dist/quill.core.css";
	import "quill/dist/quill.snow.css";
	import "quill/dist/quill.bubble.css";
	import {
		getToken
	} from "@/utils/auth";

	export default {
		name: "Editor",
		props: {
			/* 编辑器的内容 */
			value: {
				type: String,
				default: "",
			},
			/* 高度 */
			height: {
				type: Number,
				default: null,
			},
			/* 最小高度 */
			minHeight: {
				type: Number,
				default: null,
			},
			/* 只读 */
			readOnly: {
				type: Boolean,
				default: false,
			},
			// 上传文件大小限制(MB)
			fileSize: {
				type: Number,
				default: 5,
			},
			/* 类型（base64格式、url格式） */
			type: {
				type: String,
				default: "url",
			}
		},
		data() {
			return {
				uploadUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传的图片服务器地址
				headers: {
					Authorization: "Bearer " + getToken()
				},
				accept: '',
				Quill: null,
				currentValue: "",
				options: {
					theme: "snow",
					bounds: document.body,
					debug: "warn",
					modules: {
						// 工具栏配置
						toolbar: [
							["bold", "italic", "underline", "strike"], // 加粗 斜体 下划线 删除线
							["blockquote", "code-block"], // 引用  代码块
							[{
								list: "ordered"
							}, {
								list: "bullet"
							}], // 有序、无序列表
							[{
								indent: "-1"
							}, {
								indent: "+1"
							}], // 缩进
							[{
								size: ["small", false, "large", "huge"]
							}], // 字体大小
							[{
								header: [1, 2, 3, 4, 5, 6, false]
							}], // 标题
							[{
								color: ["#000000", "#e60000", "#ff9900", "#ffff00", "#008a00", "#0066cc",
									"#9933ff",
									"#ffffff", "#facccc", "#ffebcc", "#ffffcc", "#cce8cc", "#cce0f5",
									"#ebd6ff",
									"#bbbbbb", "#f06666", "#ffc266", "#ffff66", "#66b966", "#66a3e0",
									"#c285ff",
									"#888888", "#a10000", "#b26b00", "#b2b200", "#006100", "#0047b2",
									"#6b24b2",
									"#444444", "#5c0000", "#663d00", "#666600", "#003700", "#002966", "#3d1466"
								]
							}, {
								background: ["#000000", "#e60000", "#ff9900", "#ffff00", "#008a00", "#0066cc",
									"#9933ff",
									"#ffffff", "#facccc", "#ffebcc", "#ffffcc", "#cce8cc", "#cce0f5",
									"#ebd6ff",
									"#bbbbbb", "#f06666", "#ffc266", "#ffff66", "#66b966", "#66a3e0",
									"#c285ff",
									"#888888", "#a10000", "#b26b00", "#b2b200", "#006100", "#0047b2",
									"#6b24b2",
									"#444444", "#5c0000", "#663d00", "#666600", "#003700", "#002966", "#3d1466"
								]
							}], // 字体颜色、字体背景颜色
							[{
								align: []
							}], // 对齐方式
							["clean"], // 清除文本格式
							["link", "image", "video"] // 链接、图片、视频
						],
					},
					placeholder: "请输入内容",
					readOnly: this.readOnly,
				},
			};
		},
		computed: {
			styles() {
				let style = {};
				if (this.minHeight) {
					style.minHeight = `${this.minHeight}px`;
				}
				if (this.height) {
					style.height = `${this.height}px`;
				}
				return style;
			},
		},
		watch: {
			value: {
				handler(val) {
					if (val !== this.currentValue) {
						this.currentValue = val === null ? "" : val;
						if (this.Quill) {
							this.Quill.pasteHTML(this.currentValue);
						}
					}
				},
				immediate: true,
			},
		},
		mounted() {
			this.init();
		},
		beforeDestroy() {
			this.Quill = null;
		},
		methods: {
			init() {
				const editor = this.$refs.editor;
				this.Quill = new Quill(editor, this.options);
				// 如果设置了上传地址则自定义图片上传事件
				if (this.type == 'url') {
					let toolbar = this.Quill.getModule("toolbar");

					// 更改图片上传
					toolbar.addHandler("image", (value) => {
						if (value) {
							this.$refs.imageUpload.$children[0].$refs.input.click();
						} else {
							this.quill.format("image", false);
						}
					});

					// 更改视频上传
					toolbar.addHandler("video", (value) => {
						if (value) {
							this.$refs.videoUpload.$children[0].$refs.input.click();
						} else {
							this.quill.format("video", false);
						}
					});
				}
				this.Quill.pasteHTML(this.currentValue);
				this.Quill.on("text-change", (delta, oldDelta, source) => {
					const html = this.$refs.editor.children[0].innerHTML;
					const text = this.Quill.getText();
					const quill = this.Quill;
					this.currentValue = html;
					this.$emit("input", html);
					this.$emit("on-change", {
						html,
						text,
						quill
					});
				});
				this.Quill.on("text-change", (delta, oldDelta, source) => {
					this.$emit("on-text-change", delta, oldDelta, source);
				});
				this.Quill.on("selection-change", (range, oldRange, source) => {
					this.$emit("on-selection-change", range, oldRange, source);
				});
				this.Quill.on("editor-change", (eventName, ...args) => {
					this.$emit("on-editor-change", eventName, ...args);
				});
			},
			// 上传前校检格式和大小
			handleBeforeUpload(file) {
				// 校检文件大小
				if (this.fileSize) {
					const isLt = file.size / 1024 / 1024 < this.fileSize;
					if (!isLt) {
						this.$message.error(`上传文件大小不能超过 ${this.fileSize} MB!`);
						return false;
					}
				}
				return true;
			},
			handleUploadSuccess(res, file) {
				console.log('富文本上传回调', res, file)
				// 获取富文本组件实例
				let quill = this.Quill;
				// 如果上传成功
				if (res.code == 200) {
					// 获取光标所在位置
					let length = quill.getSelection().index;
					// 插入图片  res.url为服务器返回的图片地址
					if (file.raw.type.indexOf('image') != -1) quill.insertEmbed(length, "image", process.env
						.VUE_APP_BASE_API + res.fileName);
					else quill.insertEmbed(length, "video", process.env.VUE_APP_BASE_API + res.fileName);
					// 调整光标到最后
					quill.setSelection(length + 1);
				} else {
					this.$message.error("文件插入失败");
				}
			},
			handleUploadError() {
				this.$message.error("文件上传失败");
			},
		},
	};
</script>

<style>
	.editor,
	.ql-toolbar {
		white-space: pre-wrap !important;
		line-height: normal !important;
	}

	.quill-img {
		display: none;
	}

	.ql-snow .ql-tooltip[data-mode="link"]::before {
		content: "请输入链接地址:";
	}

	.ql-snow .ql-tooltip.ql-editing a.ql-action::after {
		border-right: 0px;
		content: "保存";
		padding-right: 0px;
	}

	.ql-snow .ql-tooltip[data-mode="video"]::before {
		content: "请输入视频地址:";
	}

	.ql-snow .ql-picker.ql-size .ql-picker-label::before,
	.ql-snow .ql-picker.ql-size .ql-picker-item::before {
		content: "14px";
	}

	.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="small"]::before,
	.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="small"]::before {
		content: "10px";
	}

	.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="large"]::before,
	.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="large"]::before {
		content: "18px";
	}

	.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="huge"]::before,
	.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="huge"]::before {
		content: "32px";
	}

	.ql-snow .ql-picker.ql-header .ql-picker-label::before,
	.ql-snow .ql-picker.ql-header .ql-picker-item::before {
		content: "文本";
	}

	.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="1"]::before,
	.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before {
		content: "标题1";
	}

	.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="2"]::before,
	.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before {
		content: "标题2";
	}

	.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="3"]::before,
	.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before {
		content: "标题3";
	}

	.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="4"]::before,
	.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="4"]::before {
		content: "标题4";
	}

	.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="5"]::before,
	.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="5"]::before {
		content: "标题5";
	}

	.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="6"]::before,
	.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before {
		content: "标题6";
	}

	.ql-snow .ql-picker.ql-font .ql-picker-label::before,
	.ql-snow .ql-picker.ql-font .ql-picker-item::before {
		content: "标准字体";
	}

	.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="serif"]::before,
	.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="serif"]::before {
		content: "衬线字体";
	}

	.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="monospace"]::before,
	.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="monospace"]::before {
		content: "等宽字体";
	}
</style>
